package game;

import players.*;
import cards.*;

public class Pitch {

	//Constants
	public static final int NO_BID = 0;						//null bid
	public static final int HAND_SIZE = 6;					//size of hand
	public static final int WON_SIZE = 12;					//size of stack (max)
	public static final int LOW_BID = 2;					//lowest legal bid
	public static final int HIGH_BID = 4;					//highest legal bid
	
	
	//Game Attributes
	private Deck myDeck = new Deck();								//Deck of Cards
	private Table myTable = new Table();							//Table (might also be called Round)
	private HumanPlayer p1 = new HumanPlayer("Justin");				//Player 1
	private HumanPlayer p2 = new HumanPlayer("George");				//Player 2
	
//--COORDINATE A ROUND
	public void playRound(){
		
	//SETUP
		
	//PLAY A HAND
		
		//1. Shuffle the deck   
		myDeck.shuffler();
		
		//2. Deal the cards to player (starting with non-dealer)
		dealHand();
		p1.hand.sort();
		p2.hand.sort();
		
		//3. Negotiate Bid Phase
		bidPhase();
		
		//4a. Winning bidder plays first card establishes trump 
		Card cardInAir = new Card();

		if(p1.getBid() > p2.getBid()){
			p1.setLeader(true);
			p2.setLeader(false);
		} else {
			p1.setLeader(false);
			p2.setLeader(true);
		}
		
		cardInAir = p1.isLeader() ? p1.nextPlay() : p2.nextPlay();
		
		myTable.trump = cardInAir;		//first card plays establishes trump
		myTable.pool.add(cardInAir);
		
		//4b. NonWinning bidders response to Trump
		cardInAir = !p1.isLeader() ? p1.nextPlay() : p2.nextPlay();
		myTable.pool.add(cardInAir);
		
		//4c. Establish winner of hand and clean house
		closeHand();
		
		//6. Loop through rest of hand.
		//   player one is arbitrary, the idea is that either player must have one or more
		//   cards in their hand at the start of a hand
		while(p1.hand.hasNext()){
			
			cardInAir = p1.isLeader() ? p1.nextPlay() : p2.nextPlay();
			myTable.pool.add(cardInAir);
			cardInAir = !p1.isLeader() ? p1.nextPlay() : p2.nextPlay();
			myTable.pool.add(cardInAir);
			
			closeHand();
			
		}

		//8. Stacks analyzed and points awarded
		closeRound();
		
	}

//--BID PHASE
	public void bidPhase(){
		int notdealerBid;
		int dealerBid;
		
	//1.ask non-dealer player for bid
		
		notdealerBid = p1.isDealer() ? p2.inputBid(NO_BID) : p1.inputBid(NO_BID);
		
	//2.if non-dealer passes, dealer must take it for '2'
		
		if(notdealerBid == NO_BID){
		
			//set dealer players bid equal to lowest, no choice
			if(p1.isDealer()){
				p1.setBid(LOW_BID);
				System.out.println("ok, " + p1.name + " has to take it for " + LOW_BID + "\n");
				
			} else {
				p2.setBid(LOW_BID);
				System.out.println("ok, " + p2.name + " has to take it for " + LOW_BID + "\n");
			}
		
			return;			//bid assigned, leave bid phase method
			
		}
		
		//3.otherwise dealer can choose to take it for => non-dealer bid
		dealerBid = p1.isDealer() ? p1.inputBid(notdealerBid) : p2.inputBid(notdealerBid);
		
		//figure out who won the bid
		if (dealerBid >= notdealerBid){
			if(p1.isDealer()){
				p1.setBid(dealerBid);		//player one is dealer and won the bid
			} else {
				p2.setBid(dealerBid);		//player two is dealer and won the bid
			}
		} else {
			if(p1.isDealer()){
				p2.setBid(notdealerBid);	//player one is dealer, player two won the bid
			} else {
				p1.setBid(notdealerBid);	//player two is dealer, player one won the bid
			}
		}
	}
	
//--DETERMINES WHO WON HAND
	public boolean isWinner(){
		Card thisCard = myTable.getLead();
		Card otherCard = myTable.getFollow();
		int trumpSuit = myTable.getTrump();
		
		//opponent followed suit and outranked
		if(otherCard.getSuit() == thisCard.getSuit()){
			if(otherCard.getRank() > thisCard.getRank()){
				return false;
			} else {
				return true;
			}
		//opponent didn't follow suit, but played trump?
		} else if (otherCard.getSuit() == trumpSuit) {
			return false;
		//lead wins
		} else {
			return true;
		}
		
	}
	
//--CLOSE OUT THE HAND
	//handles post hand actions
	//distributing cards to users "won" pile and communicating results
	public void closeHand(){
		//p1 lead
		if(p1.isLeader()){
			if(isWinner()){
				System.out.println(p1.name + " won the hand, gets " + myTable.pool.peek(0) + " & " + myTable.pool.peek(1));
				p1.won.add(myTable.pool.play(1));
				p1.won.add(myTable.pool.play(0));
			
			} else {
				System.out.println(p2.name + " won the hand, gets " + myTable.pool.peek(0) + " & " + myTable.pool.peek(1));
				p2.won.add(myTable.pool.play(1));
				p2.won.add(myTable.pool.play(0));
				
				p1.setLeader(false);
				p2.setLeader(true);
			}
		//p2 lead
		} else {
			if(isWinner()){
				System.out.println(p2.name + " won the hand, gets " + myTable.pool.peek(0) + " & " + myTable.pool.peek(1));
				p2.won.add(myTable.pool.deal());
				p2.won.add(myTable.pool.deal());
				
			} else {
				System.out.println(p1.name + " won the hand, gets " + myTable.pool.peek(0) + " & " + myTable.pool.peek(1));
				p1.won.add(myTable.pool.deal());
				p1.won.add(myTable.pool.deal());
				
				p1.setLeader(true);
				p2.setLeader(false);
			}
		}
	}
	
//--CLOSE OUT THE ROUND
	//1. Hand out points
	//2. puts cards from players hands back into the deck
	//NOTE: ideally there should be randomness about who does this
	//first and maybe even the order the cards end up in
	//3. Flip Dealer
	public void closeRound(){
		
		//give points to 
		awardPoints();
		
		if(p1.won.length() > 0){
			for(Card c : p1.won.getDeck()){
				myDeck.add(c);
			}
		}
		
		if(p2.won.length() > 0){
			for(Card c : p2.won.getDeck()){
				myDeck.add(c);
			}
		}
		
		myTable.reset();
		
		p1.flipDealer();
		p2.flipDealer();
		
	}
	
	//deals cards (3 per person)
	public void dealHand(){
	
		//two iterations
		for(int j = 0; j < 2; j++){
			
			//iteration 1/3
			for(int i = 0; i < 3; i++){
				if(p1.isDealer())
					p1.hand.add(myDeck.deal());
				else
					p2.hand.add(myDeck.deal());
			}
			
			//iteration 2/4
			for(int i = 0; i < 3; i++){
				if(p1.isDealer())
					p2.hand.add(myDeck.deal());
				else
					p1.hand.add(myDeck.deal());
			}
		}
		
	}
	
	public void awardPoints(){
		
		Card p1LOW = new Card();
		Card p1HIGH = new Card();
		Card p1JACK = new Card();
		int p1GAME = 0;
		int p1Score = 0;
		
		Card p2LOW = new Card();
		Card p2HIGH = new Card();
		Card p2JACK = new Card();
		int p2GAME = 0;
		int p2Score = 0;
		
		//parse player one's hand
		for(Card c : p1.won.getDeck()){
			//need to look at trump only
			if (myTable.trump.isSameSuit(c)){
				//if card is lower then current low, replace
				if( p1LOW.getRank() == 0 ){
					//this must be the lowest
					p1LOW = c;
				} else if ( p1LOW.getRank() > c.getRank() ){
					p1LOW = c;
				}
				
				//if card is higher then current high, replace
				if( p1HIGH.getRank() == 0 ){
					//this must be the highest
					p1HIGH = c;
				} else if ( p1LOW.getRank() > c.getRank() ){
					p1HIGH = c;
				}				
				
				//if card is a jack, add it
				if( c.getRank() == 11){
					p1JACK = c;
				}
			}
			
			//game is not dependent on trump, get game
			if(c.getRank() == 10){			//10s are worth 10
				p1GAME+=10;
			} else if (c.getRank() == 11){	//jacks are worth 1
				p1GAME+=1;
			} else if (c.getRank() == 12){	//queens are worth 2
				p1GAME+=2;
			} else if (c.getRank() == 13){	//kings are worth 3
				p1GAME+=3;
			} else if (c.getRank() == 14){  //aces are worth 4
				p1GAME+=4;
			}
				
		}
		
		//parse player two's hand
		for(Card c : p2.won.getDeck()){
			//need to look at trump only
			if (myTable.trump.isSameSuit(c)){
				//if card is lower then current low, replace
				if( p2LOW.getRank() == 0 ){
					//this must be the lowest
					p2LOW = c;
				} else if ( p2LOW.getRank() > c.getRank() ){
					p2LOW = c;
				}
				
				//if card is higher then current high, replace
				if( p2HIGH.getRank() == 0 ){
					//this must be the highest
					p2HIGH = c;
				} else if ( p1LOW.getRank() > c.getRank() ){
					p2HIGH = c;
				}				
				
				//if card is a jack, add it
				if( c.getRank() == 11){
					p2JACK = c;
				}
			}
			
			//game is not dependent on trump, get game
			if(c.getRank() == 10){			//10s are worth 10
				p2GAME+=10;
			} else if (c.getRank() == 11){	//jacks are worth 1
				p2GAME+=1;
			} else if (c.getRank() == 12){	//queens are worth 2
				p2GAME+=2;
			} else if (c.getRank() == 13){	//kings are worth 3
				p2GAME+=3;
			} else if (c.getRank() == 14){  //aces are worth 4
				p2GAME+=4;
			}
				
		}
		
		//compare results and assign points
		//four points are available (high, low, game, jack)
		
		//POINT FOR LOW
		//awarded for lowest trump
		if(p1LOW.getRank() > p2LOW.getRank()){
			p2Score++;
		} else {
			p1Score++;
		}
		
		//POINT FOR HIGH
		//awarded for highest trump
		if(p1HIGH.getRank() > p2HIGH.getRank()){
			p1Score++;
		} else {
			p2Score++;
		}
		
		//POINT FOR JACK
		//awarded for jack of trump (no point if no jack)
		if(p1JACK.getRank() == 11){
			p1Score++;
		} else if (p2JACK.getRank() == 11){
			p2Score++;
		}
		
		//POINT FOR GAME
		//awarded for highest count, no point if tied
		if(p1GAME > p2GAME){
			p1Score++;
		} else if (p2GAME > p1GAME) {
			p2Score++;
		}
		
		//Sets Points out scoring
		if(p1.getBid() != NO_BID){
			if(p1.getBid() > p1Score){
				//player is "set" score will be minus bid amount
				p1.addScore(-p1.getBid());
				System.out.println("Sorry " + p1.name + " you are set by " + p1.getBid() + ", current score: " + p1.getScore() );
				p2.addScore(p2Score);
				System.out.println(p2.name + ", you got " + p2Score + " points. Current Score: " + p2.getScore());
			} else {
				//player gets the points
				p1.addScore(p1Score);
				System.out.println(p1.name + ", you got " + p1Score + " points. Current Score: " + p1.getScore());
				p2.addScore(p2Score);
				System.out.println(p2.name + ", you got " + p2Score + " points. Current Score: " + p2.getScore());
			}
		} else {
			if(p2.getBid() > p2Score){
				//player is "set" score will be minus bid amount
				p2.addScore(-p2.getBid());
				System.out.println("Sorry " + p2.name + " you are set by " + p2.getBid() + ", current score: " + p2.getScore() );
				p1.addScore(p1Score);
				System.out.println(p1.name + ", you got " + p1Score + " points. Current Score: " + p1.getScore());
			} else {
				//player gets the points
				p2.addScore(p2Score);
				System.out.println(p2.name + ", you got " + p2Score + " points. Current Score: " + p2.getScore());
				p1.addScore(p1Score);
				System.out.println(p1.name + ", you got " + p1Score + " points. Current Score: " + p1.getScore());
			}
		}		
	}
	
	public static void main(String[] args) {
			
		Pitch myGame = new Pitch();
		int counter = 1;
		
		//1. decide who deals first (this could be random) [for now always player1]
		myGame.p1.flipDealer();
		
		//2. play rounds
		while(myGame.p1.getScore() < 11 || myGame.p2.getScore() < 11){					//control loop, continue until someone wins (scores 11 points)
		
			System.out.println("\n\nBegin Round " + counter + ", Good Luck");
			myGame.playRound();
			counter++;
		}
	
		System.out.println("Game Over.");
		System.out.println(myGame.p1.name + ": " + myGame.p1.getScore());
		System.out.println(myGame.p2.name + ": " + myGame.p2.getScore());		
		
	}

}